# -*- coding: utf-8 -*-
#    Copyright (C) 2012  Ruslan V. Us <unclerus@gmail.com>, Aleksandr V. Bannov <kokudzin@gmail.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import time, os, re
import _client

class ApacheLogProvider (object):
    '''
    Провайдер, предоставляющий информацию на основе логов в формате apache combined
    '''
    def __init__ (self, fileName, filters = []):
        self._cfilters = []
        for f in filters:
            f = f.decode('string-escape')
            self._cfilters.append (re.compile (f))
        self._buf = ''
        try:    
            self._file = file (fileName, 'r')
        except Exception as err:
            print err
            #sys.exit (1)

    def _process (self, data):
        assert data
        self._buf += data
        lines = self._buf.split ('\n')
        del lines [-1]
        self._buf = '' if self._buf.endswith ('\n') else lines [-1]
        result = []
        
        parts = [
            r'(?P<host>\S+)',
            r'\S+',
            r'(?P<user>\S+)',
            r'\[(?P<time>.+)\]',
            r'"(?P<request>.+)"',
            r'(?P<status>[0-9]+)',
            r'(?P<size>\S+)',
            r'"(?P<referer>.*)"',
            r'"(?P<agent>.*)"',
        ]
        
        pattern = re.compile (r'\s+'.join (parts) + r'\s*\Z')

        for line in (pattern.match (l) for l in lines):
            matched = False
            if not line:
                continue
            
            line = line.groupdict ()
            for cfilted in self._cfilters:
                res = cfilted.search (line ['request'])
                if res:
                    matched = True
                    break
            if matched:
                continue
  
            print line ['request']
            
            result.append (
                _client.Request (
                    line ['host'],
                    time.mktime (time.strptime (line ['time'].split (' ') [0], '%d/%b/%Y:%H:%M:%S')),
                    line ['request'],
                    line ['agent']
                )
            )
        return result

    def __call__ (self):
        self._file.seek (0, os.SEEK_END)
        pos = self._file.tell ()

        while True:
            self._file.seek (0, os.SEEK_END)
            newPos = self._file.tell ()
            result = None
            if pos != newPos:
                self._file.seek (pos, os.SEEK_SET)
                result = self._process (self._file.read (newPos - pos))
                pos = newPos
            yield result

